package com.wg.net.server.tcp.handle;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.wg.net.session.WebSocketSession;
import com.wg.net.NetConfig;
import com.wg.net.session.TcpSession;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;

/**
 * WebSocket服务器端处理器（处理WebSocket协议连接）
 *
 * @author 少爷123
 */
@Sharable
public class WebsocketServerHandler extends AbstractServerHandler<WebSocketFrame> {
    private static final Log log = LogFactory.get();
    /**
     * WebSocket最大包长度
     */
    private final int maxFrameLength = NetConfig.getInstance().getMaxContentLength();

    /**
     * 读取WebSocket帧并分发（核心读逻辑）
     *
     * @param ctx 当前通道上下文
     * @param wsf WebSocket帧对象
     */
    @Override
    protected final void channelRead0(ChannelHandlerContext ctx, WebSocketFrame wsf) {
        Channel channel = ctx.channel();
        String channelId = channel.id().asLongText();

        try {
            // 解析WebSocket帧内容
            ByteBuf content = wsf.content();
            int packLen = content.readInt();

            // 校验包长度有效性（防止负数或超大值）
            if (packLen < 0 || packLen > maxFrameLength) {
                log.error("无效包长 | 通道ID={}| 包长={}| 最大允许={}",
                        channelId, packLen, maxFrameLength);
                ctx.close();
                return;
            }

            // 读取实际数据
            if (content.readableBytes() < packLen) {
                log.warn("数据不完整 | 通道ID={}| 需要={}| 实际={}",
                        channelId, packLen, content.readableBytes());
                return;
            }

            byte[] data = new byte[packLen];
            content.readBytes(data);
            dispatchPacket(ctx, data);
        } catch (Exception e) {
            log.error("WebSocket帧解析异常 | 通道ID={}", channelId, e);
            ctx.close();
        }
    }

    /**
     * 处理握手完成事件（升级为WebSocket协议）
     *
     * @param ctx 通道上下文
     * @param evt 事件对象
     */
    @Override
    public final void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof HandshakeComplete) {
            log.info("WebSocket握手成功 | 通道ID={}", ctx.channel().id());
            channelActive(ctx.channel()); // 触发会话初始化
        } else {
            super.userEventTriggered(ctx, evt); // 其他事件交给父类处理
        }
    }

    /**
     * 创建WebSocket会话（具体实现）
     *
     * @param channel 当前连接通道
     * @return WebSocket会话对象
     */
    @Override
    protected TcpSession createSession(Channel channel) {
        return new WebSocketSession(channel);
    }
}